﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using Newtonsoft.Json;
using QDT.Common;
using QDT.Common.Plugins;
using QDT.Common.Plugins.Sms;
using QDT.Core.Assignments;
using QDT.Core.Deals;
using QDT.Core.Members;
using QDT.Core.Projects;
using QDT.MVC;
using QDT.P2B.Domain.Config;
using QDT.P2B.Domain.Messages;
using QDT.Services;
using QDT.Web.Models;

namespace QDT.Web.Controllers
{
    public partial class AppController : BaseController
    {
        protected static readonly string SecretKey = "kxT8s52Mz9";
        protected static readonly string Version = "1";

        public ActionResult VersionCheck(string version)
        {
            if (!version.Equals(Version))
            {
                var infos = new[]
                {
                    new {info = "更新信息1"},
                    new {info = "更新信息2"},
                    new {info = "更新信息3"},
                    new {info = "更新信息4"}
                };
                return Json(new
                {
                    version = Version,
                    url = "http://" + HttpContext.Request.Url.Authority + Url.Content("~/Content/Apk/QianDW.apk"),
                    info = infos,
                    size = "1633879"
                },
                JsonRequestBehavior.AllowGet);
            }
            return Json(new { version }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Index(int optype, string router)
        {
            switch (optype)
            {
                case 10001:
                    return RedirectToAction("Banners");
                case 10002:
                    return RedirectToAction("Home");
                case 10003:
                    return RedirectToAction("ProjectList", new { router });
                case 10004:
                    return RedirectToAction("AssignList", new { router });
                case 10005:
                    return RedirectToAction("ProjectDetail", new { router });
                case 10006:
                    return RedirectToAction("AssignDetail", new { router });
                case 10007:
                    return RedirectToAction("LoanInfo", new { router });
                case 10008:
                    return RedirectToAction("RiskControl", new { router });
                case 10009:
                    return RedirectToAction("ProjectBidList", new { router });
                case 10010:
                    return RedirectToAction("AssignBidList", new { router });
                case 10011:
                    return RedirectToAction("QueryAccount", new { router });
                case 20001:
                    return RedirectToAction("AppLogin", new { router });
                case 20002:
                    return RedirectToAction("AppRegister", new { router });
                case 20003:
                    return RedirectToAction("BindEmail", new { router });
                case 20004:
                    return RedirectToAction("BindIdCard", new { router });
                case 20005:
                    return RedirectToAction("ChangePassword", new { router });
                case 20006:
                    return RedirectToAction("InvestList", new { router });
                case 20007:
                    return RedirectToAction("LogList", new { router });
                case 20008:
                    return RedirectToAction("BindMobile", new { router });
                case 30001:
                    return RedirectToAction("InvestProject", new { router });
                case 30002:
                    return RedirectToAction("InvestAssign", new { router });
                case 90001:
                    return RedirectToAction("Images", new { router });
                case 90002:
                    return RedirectToAction("Valicodes", new { router });
                case 90003:
                    return RedirectToAction("EmailValicodes", new { router });
                default:
                    return null;
            }
        }

        [OutputCache(Duration = 600)]
        public JsonResult Banners()
        {
            ICollection<Img> imgs = new Collection<Img>();
            imgs.Add(new Img
            {
                src = "03",
                url = "http://tieba.baidu.com/p/3432495012?qq-pf-to=pcqq.discussion#10006-sqq-1-95571-df2039688de0d51ac635e03565e2e7e0&qq-pf-to=pcqq.c2c"
            });
            imgs.Add(new Img
            {
                src = "04",
                url = "http://phone.qiandw.com/Demo/qiandw/weixin.htm"
            });
            imgs.Add(new Img
            {
                src = "05",
                url = "http://phone.qiandw.com/Demo/qiandw/EconomyNew.htm"
            });
            imgs.Add(new Img
            {
                src = "06",
                url = "http://phone.qiandw.com/Demo/qiandw/Certificate.htm"
            });
            imgs.Add(new Img
            {
                src = "07",
                url = "http://phone.qiandw.com/Demo/qiandw/Inspect.htm"
            });
            imgs.Add(new Img
            {
                src = "08",
                url = "http://phone.qiandw.com/Demo/qiandw/qianbao.htm"
            });
            return Json(new { imgs }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 600)]
        public JsonResult Home()
        {
            var hasProject =
                DbProvider.D<Project>()
                    .Any(x => x.InnerStatus == (int)ProjectStatus.Progress && !x.IsOffline && x.IsEffect && !x.IsDelete);
            var hasAssign =
                DbProvider.D<Assignment>()
                    .Any(x => x.InnerStatus == (int)AssignmentStatus.Progress && !x.IsOffline && x.IsEffect &&
                            !x.IsDelete);
            var status = new
            {
                h10001 = hasProject ? "1" : "0",
                h10002 = hasAssign ? "1" : "0",
            };
            return Json(new { status }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 600, VaryByParam = "router")]
        public JsonResult ProjectList(string router = "1")
        {

            const int pageSize = 20;
            var pageNumber = Convert.ToInt32(router);

            var filter = PredicateExtensionses.True<Project>();

            filter = filter.And(x => x.TypeID != 7);

            var porjects = DbProvider.D<Project>()
                .Where(filter.And(x => !x.IsDelete && x.IsEffect && x.StartTime.HasValue && x.ID > 182 && !x.IsOffline))
                .OrderByDescending(x => x.ID)
                .ToPagedList(pageNumber - 1, pageSize).ToList();

            ICollection<ProjectDto> ps = new Collection<ProjectDto>();
            porjects.Each(x => ps.Add(new ProjectDto(x)));

            return Json(new { plist = ps, currentpage = router, totalpage = "10" }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 60, VaryByParam = "router")]
        public JsonResult ProjectDetail(string router = "0")
        {
            var pid = Convert.ToInt32(router);
            Project project;
            if (pid == 0)
            {
                project =
                    DbProvider.D<Project>()
                        .OrderByDescending(x => x.ID)
                        .FirstOrDefault(x => x.InnerStatus > 0 && x.InnerStatus != 2 && !x.IsOffline && x.IsEffect && !x.IsDelete);
            }
            else
            {
                project = DbProvider.GetByID<Project>(pid);
            }
            var credits = DbProvider.D<Credit>().Where(x => x.ProjectID == project.ID && x.AssignmentID == 0);

            var p = new ProjectDto(project)
            {
                investcount = credits.Count().ToString(),
            };

            return Json(new { project = p }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 600, VaryByParam = "router")]
        public JsonResult AssignList(string router = "1")
        {
            const int pageSize = 20;
            var pageNumber = Convert.ToInt32(router);
            var assignments =
                DbProvider.D<Assignment>()
                    .Where(x => !x.IsDelete && x.IsEffect && !x.IsOffline)
                    .OrderBy(x => x.InnerStatus).ThenByDescending(x => x.ID)
                    .ToPagedList(pageNumber - 1, pageSize).ToList();

            ICollection<AssignDto> assigns = new Collection<AssignDto>();
            assignments.Each(x => assigns.Add(new AssignDto(x)));

            return Json(new { alist = assigns, currentpage = router, totalpage = "10" }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 60, VaryByParam = "router")]
        public JsonResult AssignDetail(string router = "0")
        {
            var aid = Convert.ToInt32(router);
            Assignment assign;
            if (aid == 0)
            {
                assign =
                    DbProvider.D<Assignment>()
                    .OrderByDescending(x => x.ID)
                        .FirstOrDefault(x => !x.IsOffline && x.IsEffect && !x.IsDelete);
            }
            else
            {
                assign = DbProvider.GetByID<Assignment>(aid);
            }

            var credits = DbProvider.D<Credit>().Where(x => x.AssignmentID == assign.ID);

            var a = new AssignDto(assign)
            {
                investcount = credits.Count().ToString(),
                pstart = DbProvider.GetByID<Project>(assign.ProjectId).StartTime.Value.ToString("yyyy-MM-dd HH:mm:ss")
            };
            return Json(new { assign = a }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 600, VaryByParam = "router")]
        public JsonResult LoanInfo(string router = "0")
        {
            var pid = Convert.ToInt32(router);
            var p = DbProvider.GetByID<Project>(pid);
            if (p == null)
            {
                return null;
            }
            return Json(new { loaninfo = p.Parent.LoanInfo, description = p.Parent.Description }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 600, VaryByParam = "router")]
        public JsonResult RiskControl(string router = "0")
        {
            var pid = Convert.ToInt32(router);
            var p = DbProvider.GetByID<Project>(pid);
            if (p == null)
            {
                return null;
            }
            return Json(new { riskcontrol = p.Parent.RiskControl }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 60, VaryByParam = "router")]
        public JsonResult ProjectBidList(string router = "0")
        {
            var pid = Convert.ToInt32(router);

            var credits = DbProvider.D<Credit>().Where(x => x.ProjectID == pid && x.AssignmentID == 0);
            ICollection<InvestRecordDto> invests = new Collection<InvestRecordDto>();
            credits.Each(x => invests.Add(new InvestRecordDto(x)));

            return Json(new { invests }, JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Duration = 60, VaryByParam = "router")]
        public JsonResult AssignBidList(string router = "0")
        {
            var aid = Convert.ToInt32(router);

            var credits = DbProvider.D<Credit>().Where(x => x.AssignmentID == aid);
            ICollection<InvestRecordDto> invests = new Collection<InvestRecordDto>();
            credits.Each(x => invests.Add(new InvestRecordDto(x)));

            return Json(new { invests }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Images(string router)
        {
            try
            {
                var filePath = System.Web.HttpContext.Current.Server.MapPath("../Content/Default/Images/App/{0}.jpg".FormatWith(router));

                var fileInfo = new FileInfo(filePath);

                Response.ContentType = "image/jpg";
                Response.WriteFile(fileInfo.FullName);
                Response.AddHeader("Content-Length", fileInfo.Length.ToString("0"));
                Response.End();
                return null;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        public JsonResult Valicodes(string router)
        {

            var model = JsonConvert.DeserializeObject<SendSmsModel>(string.IsNullOrEmpty(router) ? "" : router);

            if (!(model.mobile + SecretKey).Hash().ToUpper().Equals(model.token.ToUpper()))
            {
                return Json(new { status = "-999", info = "未知异常" }, JsonRequestBehavior.AllowGet);
            }

            var pattern = new Regex(@"^1[3-9][0-9]\d{8}$");
            if (!model.mobile.Match(pattern)) return Json(new { result = "-1", msg = "手机号码格式不正确" }, JsonRequestBehavior.AllowGet);

            if (model.type == "0")
            {
                var isHas = DbProvider.D<User>().Any(x => x.Mobile == model.mobile && x.MobilePassed);
                if (isHas) return Json(new { result = "-2", msg = "手机号码已被注册" }, JsonRequestBehavior.AllowGet);
            }

            const int type = (int)MsgType.SMS;
            var time = DateTime.Now.AddSeconds(-3);
            var day = DateTime.Now.Date;

            var source = DbProvider.D<MsgQueue>().Any(x => x.InnerType == type && x.CreateTime > time && x.Dest == model.mobile);
            if (source)
            {
                return Json(new { result = "-3", msg = "90秒内不能重发" }, JsonRequestBehavior.AllowGet);
            }

            var count = DbProvider.D<MsgQueue>().Count(x => x.InnerType == type && x.CreateTime > day && x.Dest == model.mobile);
            if (count >= 1000)
            {
                return Json(new { result = "-4", msg = "当天发送短信数超额" }, JsonRequestBehavior.AllowGet);
            }

            var vCode = IoC.Resolve<ValidateImage>();
            var code = vCode.CreateValidateCode(4);

            var msg = new MsgQueueFactory().CreateValidatorMsg(model.mobile, code);
            DbProvider.Add(msg);
            DbProvider.SaveChanges();

            QuickSendSMS(msg);

            return Json(new { result = "1", code = code.Hash().ToLower(), msg = "发送成功" }, JsonRequestBehavior.AllowGet);
        }

        public JsonResult EmailValicodes(string router)
        {
            var model = JsonConvert.DeserializeObject<SendEmailModel>(string.IsNullOrEmpty(router) ? "" : router);

            if (!(model.email + SecretKey).Hash().ToUpper().Equals(model.token.ToUpper()))
            {
                return Json(new { status = "-999", info = "未知异常" }, JsonRequestBehavior.AllowGet);
            }

            var pattern = new Regex(@"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$");
            if (!model.email.Match(pattern)) return Json(new { result = "-1", Msg = "邮箱格式不正确" }, JsonRequestBehavior.AllowGet);

            var isHas = DbProvider.D<User>().Any(x => x.Email == model.email && x.MobilePassed);
            if (model.type == "0")
            {
                if (isHas) return Json(new { result = "-2", msg = "邮箱已被注册" }, JsonRequestBehavior.AllowGet);
            }
            if (model.type == "1")
            {
                if (!isHas) return Json(new { result = "-3", msg = "无效邮箱" }, JsonRequestBehavior.AllowGet);
            }

            var vCode = IoC.Resolve<ValidateImage>();
            var code = vCode.CreateValidateCode(4);

            var content = "验证码 : " + code;
            var msg = new MsgQueueFactory().CreateValidatorMsg(model.email, "众禧贷邮箱验证", content);
            msg.Level = 2;
            DbProvider.Add(msg);
            DbProvider.SaveChanges();

            return Json(new { result = "1", code = code.Hash().ToLower(), msg = "发送成功" }, JsonRequestBehavior.AllowGet);
        }

        public void QuickSendSMS(MsgQueue msg)
        {

            DbProvider.Refresh(msg);

            if (msg.IsSend)
            {
                return;
            }

            msg.UpdateSend();

            string type = SettingManager.Get<MessageConfig>().SmsType;

            var smsSever = DbProvider.D<SmsServer>().FirstOrDefault(x => x.ClassName == type);

            if (smsSever == null)
            {
                var m = DbProvider.GetByID<MsgQueue>(msg.ID);
                m.IsSuccess = false;
                m.Result = "未设置默认短信通道";
                DbProvider.SaveChanges();
                return;
            }

            var sender = SMSSender.CreateInstance(new SMSAttribute
            {
                Config = smsSever.Config.Values.ToArray(),
                Name = smsSever.ServerName,
                SmsAccount = smsSever.UserName,
                SmsPassword = smsSever.Password,
                TypeName = smsSever.ClassName
            });


            if (sender == null)
            {
                var m = DbProvider.GetByID<MsgQueue>(msg.ID);
                m.IsSuccess = false;
                m.Result = "短信通道不存在";
                DbProvider.SaveChanges();
                return;
            }

            try
            {
                sender.Send(msg.Dest, msg.Content);
                var m = DbProvider.GetByID<MsgQueue>(msg.ID);
                m.IsSuccess = true;
                DbProvider.SaveChanges();
            }
            catch (Exception ex)
            {
                var m = DbProvider.GetByID<MsgQueue>(msg.ID);
                m.IsSuccess = false;
                m.Result = ex.Message;
                DbProvider.SaveChanges();
            }
        }

    }
}
